﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using BReusable.Extensions.HtmlExtensions;

namespace BReusable.PivotalTracker
{
	public class PivotalTrackerAPI
	{


		public const string StrPivotalTrackerApi = "http://www.pivotaltracker.com/services/v2/";
		public const string StrPivotalTrackerProjects = "http://www.pivotaltracker.com/services/v2/projects/";


		readonly PivotalTrackerToken _token;
		public PivotalTrackerAPI(PivotalTrackerToken token)
		{
			Debug.Assert(token != null);
			Debug.Assert(token.Token.IsNullOrEmpty() == false);
			_token = token;

		}

		


		private string GetPage(string location)
		{
			return GetPage(new Uri(location), null);
		}
		private string GetPage(Uri location, IDictionary<string, string> headerValues)
		{
			var request = _token.GetRequest(location);
			if (headerValues != null)
				headerValues.ForEach(pair => request.Headers.Add(pair.Key, pair.Value));
			return BHttpLib.FromRequestGetResponseString(request);
		}
		//private string GetPagePost(string location, Dictionary<string, string> postData)
		//{
		//    var request = _token.GetPagePost(new Uri(location), postData);

		//    return HttpLib.FromRequestGetResponseString(request);
		//}




		public String GetActivityFeed()
		{
			return GetPage(StrPivotalTrackerApi + "activities");
		}
		public String GetProjectActivity(String projectId)
		{
			return GetPage(StrPivotalTrackerProjects + projectId + "/activities");
		}

		public String GetProjectByIdXML(String projectId)
		{
			return GetPage(StrPivotalTrackerProjects + projectId);
		}
		public PivotalTrackerProject GetProjectByName(string name)
		{
			var projects = GetallMyProjects();
			return projects.Where(item => item.Name == name).SingleOrDefault();
		}

		public String GetAllMyProjectsXML()
		{
			return GetPage(StrPivotalTrackerProjects);
		}

		/// <summary>
		/// XElement does not include the root, XDocument does
		/// </summary>
		/// <param name="xmlString"></param>
		/// <returns></returns>
		private static XElement GetXElementFromXmlString(string xmlString)
		{
			using (var sw = new System.IO.StringReader(xmlString))
			{
				return XElement.Load(sw);
			}
		}


		public IQueryable<PivotalTrackerProject> GetallMyProjects()
		{
			var result = new List<PivotalTrackerProject>();

			var xe = GetXElementFromXmlString(GetAllMyProjectsXML());
			//var xd=System.Xml.Linq.XDocument.Load(sw);
			//var projects = xd.Elements("Projects");
			var projects = from p in xe.Elements("project") select p;

			foreach (var item in projects)
				// ReSharper disable PossibleNullReferenceException
				result.Add(new PivotalTrackerProject((int)item.Element("id"), item.Element("name").Value));
				// ReSharper restore PossibleNullReferenceException
			return result.AsQueryable();

		}
		public String GetIterationsXML(String projectId)
		{
			return GetPage(StrPivotalTrackerProjects + projectId + "/iterations");
		}
		public enum StoryType
		{
			Feature, Bug, Chore, Release
		}
		public string AddStoryXML(string projectId, StoryType storyType, string name, string description)
		{
			var story = storyType.ToString().WrapInHtmlTag("story_type") + name.WrapInHtmlTag("name") + description.WrapInHtmlTag("description");
			var request = _token.GetPagePostXML(new Uri(StrPivotalTrackerProjects + projectId + "/stories"), story.WrapInHtmlTag("story"));
            return BHttpLib.FromRequestGetResponseString(request);
		}

		public PivotalTrackerStory AddStory(string projectId, StoryType storyType, string name, string description)
		{
			return new PivotalTrackerStory(GetXElementFromXmlString(AddStoryXML(projectId, storyType, name, description)));
		}
		public string AddStoryCommentXML(string projectId, string storyId, string comment)
		{
			throw new NotImplementedException();
		}

		public string DeleteStoryXML(string projectId, string storyId)
		{
			throw new NotImplementedException();
		}

		public enum IterationType
		{
			Done, Current, Backlog
		}
		public String GetIterations(String projectId, IterationType iteration)
		{
			return GetPage(StrPivotalTrackerProjects + projectId + "/" + iteration);
		}
		public class IterationsFilter
		{
			/// <summary>
			/// Can be negative to get Done iterations
			/// </summary>
			public int? Offset { get; set; }
			public int? Limit { get; set; }
			public IterationType? Type { get; set; }
			public override string ToString()
			{
				var result = new StringBuilder();
				if (Type.HasValue)
				{
					result.Append("/" + Type);
				}
				if (Offset.HasValue)
				{
					result.Append("?offset=" + Offset.Value);
					if (Limit.HasValue)
						result.Append("&limit=" + Limit.Value);
				}
				else if (Limit.HasValue)
				{
					result.Append("?limit=" + Limit.Value);
				}
				return result.ToString();
			}
		}
		public String GetIterations(String projectId, IterationsFilter filter)
		{
			return GetPage(StrPivotalTrackerApi + projectId + "/iterations" + filter);
		}


	}
}
